home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / mweb / MWEB Utils / ws295sdk.exe / Ws2sdkzp.exe / SAMPLES / LAYERED / LLIST.H < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-06  |  10.1 KB  |  459 lines

  1. /*++
  2.  
  3. Module Name:
  4.  
  5.     llist.h
  6.  
  7. Abstract:
  8.  
  9.     This  module  is  a  standalone  collection  of  linked-list definition and
  10.     manipulation  macros  originally  defined  within  the  Windows NT
  11.     development.
  12.  
  13. --*/
  14.  
  15. #ifndef _LLIST_
  16. #define _LLIST_
  17. #include <winsock2.h>
  18.  
  19.  
  20.  
  21. #if !defined( _WINNT_ )
  22. //
  23. //  From NTDEF.H.
  24. //
  25.  
  26. //  Doubly  linked  list  structure.   Can be used as either a list head, or as
  27. //  link storage within a linked-list item.
  28.  
  29. typedef struct _LIST_ENTRY {
  30.    struct _LIST_ENTRY *Flink;
  31.    struct _LIST_ENTRY *Blink;
  32. } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
  33.  
  34.  
  35.  
  36.  
  37. // LONG
  38. // FIELD_OFFSET(
  39. //     IN <typename>   type,
  40. //     IN <fieldname>  field
  41. //     );
  42. #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
  43. /*++
  44.  
  45. Routine Description:
  46.  
  47.     Calculates  the  byte offset of a field in a structure of type "type".  The
  48.     offset is from the beginning of the containing structure.
  49.  
  50.     Note  that  since  this macro uses compile-time type knowledge, there is no
  51.     equivalent C procedure for this macro.
  52.  
  53. Arguments:
  54.  
  55.     type  - Supplies the type name of the containing structure.
  56.  
  57.     field - Supplies  the  field  name  of  the  field  whose  offset  is to be
  58.             computed.
  59.  
  60. Return Value:
  61.  
  62.     Returns  the byte offset of the named field within a structure of the named
  63.     type.
  64. --*/
  65.  
  66.  
  67.  
  68.  
  69. // <typename> FAR *
  70. // CONTAINING_RECORD(
  71. //     IN PVOID       address,
  72. //     IN <typename>  type,
  73. //     IN <fieldname> field
  74. //     );
  75. #define CONTAINING_RECORD(address, type, field) ((type FAR *)( \
  76.                                           (PCHAR)(address) - \
  77.                                           (PCHAR)(&((type *)0)->field)))
  78. /*++
  79.  
  80. Routine Description:
  81.  
  82.     Retrieves  a  typed  pointer to a linked list item given the address of the
  83.     link  storage  structure  embedded in the linked list item, the type of the
  84.     linked  list  item,  and  the  field  name  of  the  embedded  link storage
  85.     structure.
  86.  
  87.     Note  that  since  this macro uses compile-time type knowledge, there is no
  88.     equivalent C procedure for this macro.
  89.  
  90. Arguments:
  91.  
  92.     address - Supplies  the  address of a LIST_ENTRY structure embedded in an a
  93.               linked list item.
  94.  
  95.     type    - Supplies  the  type  name  of  the  containing  linked  list item
  96.               structure.
  97.  
  98.     field   - Supplies  the  field  name  if  the LIST_ENTRY structure embedded
  99.               within the linked list item structure.
  100.  
  101. Return Value:
  102.  
  103.     Returns a pointer to the linked list item.
  104. --*/
  105.  
  106.  
  107. #endif  // !defined( _WINNT_ )
  108.  
  109.  
  110. //
  111. //  From NTRTL.H.
  112. //
  113.  
  114. //  Doubly-linked list manipulation routines.  Implemented as macros
  115. //  but logically these are procedures.
  116.  
  117.  
  118.  
  119.  
  120. // VOID
  121. // InitializeListHead(
  122. //     IN PLIST_ENTRY ListHead
  123. //     );
  124. #define InitializeListHead(ListHead) (\
  125.     (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  126. /*++
  127.  
  128. Routine Description:
  129.  
  130.     Initializes  a  PLIST_ENTRY  structure to be the head of an initially empty
  131.     linked list.
  132.  
  133. Arguments:
  134.  
  135.     ListHead - Supplies a reference to the structure to be initialized.
  136.  
  137. Return Value:
  138.  
  139.     None
  140. --*/
  141.  
  142.  
  143.  
  144.  
  145. // BOOLEAN
  146. // IsListEmpty(
  147. //     IN PLIST_ENTRY ListHead
  148. //     );
  149. #define IsListEmpty(ListHead) \
  150.     ((ListHead)->Flink == (ListHead))
  151. /*++
  152.  
  153. Routine Description:
  154.  
  155.     Determines whether or not a list is empty.
  156.  
  157. Arguments:
  158.  
  159.     ListHead - Supplies  a  reference  to  the  head  of  the linked list to be
  160.                examined.
  161.  
  162. Return Value:
  163.  
  164.     TRUE  - The linked list is empty.
  165.  
  166.     FALSE - The linked list contains at least one item.
  167. --*/
  168.  
  169.  
  170.  
  171.  
  172. // PLIST_ENTRY
  173. // RemoveHeadList(
  174. //     IN PLIST_ENTRY ListHead
  175. //     );
  176. #define RemoveHeadList(ListHead) \
  177.     (ListHead)->Flink;\
  178.     {RemoveEntryList((ListHead)->Flink)}
  179. /*++
  180.  
  181. Routine Description:
  182.  
  183.     Removes  the  "head" (first) item from a linked list, returning the pointer
  184.     to  the  removed  entry's embedded linkage structure.  Attempting to remove
  185.     the  head  item  from  a  (properly  initialized)  linked  list is a no-op,
  186.     returning the pointer to the head of the linked list.
  187.  
  188.     The  caller  may  use  the  CONTAINING_RECORD macro to amplify the returned
  189.     linkage structure pointer to the containing linked list item structure.
  190.  
  191. Arguments:
  192.  
  193.     ListHead - Supplies  a  reference  to  the  head  of  the linked list to be
  194.                operated upon.
  195.  
  196. Return Value:
  197.  
  198.     Returns  a pointer to the newly removed linked list item's embedded linkage
  199.     structure, or the linked list head in the case of an empty list.
  200. --*/
  201.  
  202.  
  203.  
  204.  
  205. // PLIST_ENTRY
  206. // RemoveTailList(
  207. //     IN PLIST_ENTRY ListHead
  208. //     );
  209. #define RemoveTailList(ListHead) \
  210.     (ListHead)->Blink;\
  211.     {RemoveEntryList((ListHead)->Blink)}
  212. /*++
  213.  
  214. Routine Description:
  215.  
  216.     Removes the "tail" (last) item from a linked list, returning the pointer to
  217.     the  removed  entry's embedded linkage structure.  Attempting to remove the
  218.     tail  item  from a (properly initialized) linked list is a no-op, returning
  219.     the pointer to the head of the linked list.
  220.  
  221.     The  caller  may  use  the  CONTAINING_RECORD macro to amplify the returned
  222.     linkage structure pointer to the containing linked list item structure.
  223.  
  224. Arguments:
  225.  
  226.     ListHead - Supplies  a  reference  to  the  head  of  the linked list to be
  227.                operated upon.
  228.  
  229. Return Value:
  230.  
  231.     Returns  a pointer to the newly removed linked list item's embedded linkage
  232.     structure, or the linked list head in the case of an empty list.
  233. --*/
  234.  
  235.  
  236.  
  237.  
  238. // VOID
  239. // RemoveEntryList(
  240. //     IN PLIST_ENTRY Entry
  241. //     );
  242. #define RemoveEntryList(Entry) {\
  243.     PLIST_ENTRY _EX_Blink;\
  244.     PLIST_ENTRY _EX_Flink;\
  245.     _EX_Flink = (Entry)->Flink;\
  246.     _EX_Blink = (Entry)->Blink;\
  247.     _EX_Blink->Flink = _EX_Flink;\
  248.     _EX_Flink->Blink = _EX_Blink;\
  249.     }
  250. /*++
  251.  
  252. Routine Description:
  253.  
  254.     Removes  an  item  from a linked list.  Attempting to remove the head of an
  255.     empty list is a no-op.
  256.  
  257. Arguments:
  258.  
  259.     Entry - Supplies  a reference to the linkage structure embedded in a linked
  260.             list item structure.
  261.  
  262. Return Value:
  263.  
  264.     None
  265. --*/
  266.  
  267.  
  268.  
  269.  
  270. // VOID
  271. // InsertTailList(
  272. //     IN PLIST_ENTRY ListHead,
  273. //     IN PLIST_ENTRY Entry
  274. //     );
  275. #define InsertTailList(ListHead,Entry) {\
  276.     PLIST_ENTRY _EX_Blink;\
  277.     PLIST_ENTRY _EX_ListHead;\
  278.     _EX_ListHead = (ListHead);\
  279.     _EX_Blink = _EX_ListHead->Blink;\
  280.     (Entry)->Flink = _EX_ListHead;\
  281.     (Entry)->Blink = _EX_Blink;\
  282.     _EX_Blink->Flink = (Entry);\
  283.     _EX_ListHead->Blink = (Entry);\
  284.     }
  285. /*++
  286.  
  287. Routine Description:
  288.  
  289.     Inserts a new item as the "tail" (last) item of a linked list.
  290.  
  291. Arguments:
  292.  
  293.     ListHead - Supplies  a  reference  to  the  head  of  the linked list to be
  294.                operated upon.
  295.  
  296.     Entry    - Supplies  a  reference  to the linkage structure embedded in the
  297.                linked list item to be added to the linked list.
  298.  
  299. Return Value:
  300.  
  301.     None
  302. --*/
  303.  
  304.  
  305.  
  306.  
  307. // VOID
  308. // InsertHeadList(
  309. //     IN PLIST_ENTRY ListHead,
  310. //     IN PLIST_ENTRY Entry
  311. //     );
  312. #define InsertHeadList(ListHead,Entry) {\
  313.     PLIST_ENTRY _EX_Flink;\
  314.     PLIST_ENTRY _EX_ListHead;\
  315.     _EX_ListHead = (ListHead);\
  316.     _EX_Flink = _EX_ListHead->Flink;\
  317.     (Entry)->Flink = _EX_Flink;\
  318.     (Entry)->Blink = _EX_ListHead;\
  319.     _EX_Flink->Blink = (Entry);\
  320.     _EX_ListHead->Flink = (Entry);\
  321.     }
  322. /*++
  323.  
  324. Routine Description:
  325.  
  326.     Inserts a new item as the "head" (first) item of a linked list.
  327.  
  328. Arguments:
  329.  
  330.     ListHead - Supplies  a  reference  to  the  head  of  the linked list to be
  331.                operated upon.
  332.  
  333.     Entry    - Supplies  a  reference  to the linkage structure embedded in the
  334.                linked list item to be added to the linked list.
  335.  
  336. Return Value:
  337.  
  338.     None
  339. --*/
  340.  
  341.  
  342.  
  343. //
  344. //
  345. //  PSINGLE_LIST_ENTRY
  346. //  PopEntryList(
  347. //      PSINGLE_LIST_ENTRY ListHead
  348. //      );
  349. //
  350.  
  351. #define PopEntryList(ListHead) \
  352.     (ListHead)->Next;\
  353.     {\
  354.         PSINGLE_LIST_ENTRY FirstEntry;\
  355.         FirstEntry = (ListHead)->Next;\
  356.         if (FirstEntry != NULL) {     \
  357.             (ListHead)->Next = FirstEntry->Next;\
  358.         }                             \
  359.     }
  360.  
  361.  
  362. //
  363. //  VOID
  364. //  PushEntryList(
  365. //      PSINGLE_LIST_ENTRY ListHead,
  366. //      PSINGLE_LIST_ENTRY Entry
  367. //      );
  368. //
  369.  
  370. #define PushEntryList(ListHead,Entry) \
  371.     (Entry)->Next = (ListHead)->Next; \
  372.     (ListHead)->Next = (Entry)
  373.  
  374.  
  375. // Samples:
  376. //
  377. // //
  378. // //  Define a list head.
  379. // //
  380. //
  381. // LIST_ENTRY FooList;
  382. //
  383. // //
  384. // //  Define a structure that will be on the list.
  385. // //
  386. // //  NOTE:  For debugging purposes, it usually makes life simpler to make the
  387. // //  LIST_ENTRY  the  first  field  of  the  structure,  but  this  is  not a
  388. // //  requirement.
  389. // //
  390. //
  391. // typedef struct _FOO
  392. // {
  393. //     LIST_ENTRY FooListEntry;
  394. //     .
  395. //     .
  396. //     .
  397. //
  398. // } FOO, * PFOO;
  399. //
  400. // //
  401. // //  Initialize an empty list.
  402. // //
  403. //
  404. // InitializeListHead( &FooList );
  405. //
  406. // //
  407. // //  Create an object, append it to the end of the list.
  408. // //
  409. //
  410. // PFOO foo;
  411. //
  412. // foo = ALLOC( sizeof(FOO) );
  413. // {check for errors, initialize FOO structure}
  414. //
  415. // InsertTailList( &FooList, &foo->FooListEntry );
  416. //
  417. // //
  418. // //  Scan list and delete selected items.
  419. // //
  420. //
  421. // PFOO foo;
  422. // PLIST_ENTRY listEntry;
  423. //
  424. // listEntry = FooList.Flink;
  425. //
  426. // while( listEntry != &FooList )
  427. // {
  428. //     foo = CONTAINING_RECORD( listEntry,
  429. //                              FOO,
  430. //                              FooListEntry );
  431. //     listEntry = listEntry->Flink;
  432. //
  433. //     if( SomeFunction( foo ) )
  434. //     {
  435. //         RemoveEntryList( &foo->FooListEntry );
  436. //      FREE( foo );
  437. //     }
  438. // }
  439. //
  440. // //
  441. // //  Purge all items from a list.
  442. // //
  443. //
  444. // PFOO foo;
  445. // PLIST_ENTRY listEntry;
  446. //
  447. // while( !IsListEmpty( &FooList ) )
  448. // {
  449. //     listEntry = RemoveHeadList( &FooList );
  450. //     foo = CONTAINING_RECORD( listEntry,
  451. //                              FOO,
  452. //                              FooListEntry );
  453. //
  454. //     FREE( foo );
  455. // }
  456.  
  457.  
  458. #endif  // _LLIST_
  459.